# original problem:
# http://groups.google.com/group/sequel-talk/browse_thread/thread/7523677c13929370

# select market, minute(from_unixtime(ack)) AS minute, round(avg((ack -  
# created_at) * 1000), 2) AS ack_average from orders  where 'ack' >  
# (UNIX_TIMESTAMP(now()) - (15 * 60) and 'market' = 'ICE' group by  
# minute(from_unixtime(ack));

# market = 'ICE'
# ack_stamp = 15.minutes.ago
# Order.query do
#   select do
#     :market,
#     :minute[:from_unixtime[:ack]].AS :minute
#     :round[:avg[(:ack - :created_at) * 1000], 2].AS :ack_average
#   end
#   where do
#     :ack > ack_stamp
#     :market == market
#   end
#   group_by :minute[:from_unixtime[:ack]]
# end

class Sequel::Dataset
  def literal(v)
    case v
    when Function, ColumnAlias: v.to_s(self)
    else
      super
    end
  end
end

class Function
  attr_reader :fun
  attr_reader :args
  
  def initialize(fun, *args)
    @fun = fun
    @args = args
  end
  
  def to_s(ds = nil)
    ds ||= Sequel::Dataset.new(nil)
    args = @args.empty? ? '' : ds.literal(@args)
    "#{@fun}(#{args})"
  end
end

class ColumnAlias
  attr_reader :expr
  attr_reader :alias
  
  def initialize(expr, ali)
    @expr = expr
    @alias = ali
  end
  
  def to_s(ds = nil)
    ds ||= Sequel::Dataset.new(nil)
    "#{ds.literal(@expr)} AS #{ds.literal(@alias)}"
  end
end

class Symbol
  def [](*args)
    Function.new(self, *args)
  end
  def as(sym)
    ColumnAlias.new(self, sym)
  end
  alias_method :AS, :as
end

class Object
  def as(sym)
    ColumnAlias.new(self, sym)
  end
  alias_method :AS, :as
end